{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "21f77178",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "step is :  0 , cost is:  0.6931471805599454\n",
      "step is :  10 , cost is:  0.6749270996455844\n",
      "step is :  20 , cost is:  0.6536948448395565\n",
      "step is :  30 , cost is:  0.6119982252990597\n",
      "step is :  40 , cost is:  0.5740688591662242\n",
      "step is :  50 , cost is:  0.5428159287041716\n",
      "step is :  60 , cost is:  0.547146806744106\n",
      "step is :  70 , cost is:  0.5213615329880068\n",
      "step is :  80 , cost is:  0.5097662528241625\n",
      "step is :  90 , cost is:  0.4760104720336926\n",
      "step is :  100 , cost is:  0.43209796944392787\n",
      "step is :  110 , cost is:  0.41879900119810576\n",
      "step is :  120 , cost is:  0.35846273734389594\n",
      "step is :  130 , cost is:  0.4290686932748198\n",
      "step is :  140 , cost is:  0.2987221564093798\n",
      "step is :  150 , cost is:  0.31376380170881835\n",
      "step is :  160 , cost is:  0.23954931171350433\n",
      "step is :  170 , cost is:  0.26631239648030036\n",
      "step is :  180 , cost is:  0.36235798353982374\n",
      "step is :  190 , cost is:  0.15166319890004298\n",
      "step is :  200 , cost is:  0.0957007625304876\n",
      "step is :  210 , cost is:  0.15284376452058274\n",
      "step is :  220 , cost is:  0.014287439824379938\n",
      "step is :  230 , cost is:  0.011520166780923012\n",
      "step is :  240 , cost is:  0.04468047024468288\n",
      "step is :  250 , cost is:  0.0535780533193499\n",
      "step is :  260 , cost is:  0.03292331887865426\n",
      "step is :  270 , cost is:  0.028395278983702463\n",
      "step is :  280 , cost is:  0.17866498872390552\n",
      "step is :  290 , cost is:  0.07173897079613964\n",
      "step is :  300 , cost is:  -0.18398023240008707\n",
      "step is :  310 , cost is:  -0.2736955886099167\n",
      "step is :  320 , cost is:  -0.0801941358124114\n",
      "step is :  330 , cost is:  0.029627322083605967\n",
      "step is :  340 , cost is:  -0.2615753871652437\n",
      "step is :  350 , cost is:  -0.14597576589707487\n",
      "step is :  360 , cost is:  -0.195491308698359\n",
      "step is :  370 , cost is:  -0.11094698110464331\n",
      "step is :  380 , cost is:  -0.2500291574095396\n",
      "step is :  390 , cost is:  -0.26893782033792324\n",
      "step is :  400 , cost is:  -0.20618947378165084\n",
      "step is :  410 , cost is:  -0.39710717850619026\n",
      "step is :  420 , cost is:  -0.5793091806595125\n",
      "step is :  430 , cost is:  -0.35106078704685906\n",
      "step is :  440 , cost is:  -0.21627410079421744\n",
      "step is :  450 , cost is:  -0.6339455453109406\n",
      "step is :  460 , cost is:  -0.48695516127589916\n",
      "step is :  470 , cost is:  -0.49242272146267996\n",
      "step is :  480 , cost is:  -0.008666249759348044\n",
      "step is :  490 , cost is:  -0.11243227193791377\n",
      "trian is over\n",
      "accuracy is :  0.9555555555555556\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x432 with 64 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 2021260153 \n",
    "import matplotlib.pyplot as plt \n",
    "from sklearn.datasets import load_digits\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.model_selection import train_test_split\n",
    "import math\n",
    "from collections import Counter\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "\n",
    "infinity = float(-2**31)\n",
    " \n",
    "def sigmodFormatrix(Xb,thetas):\n",
    "    params = - Xb.dot(thetas)\n",
    "    r = np.zeros(params.shape[0])#返回一个np数组\n",
    "    for i in range(len(r)):\n",
    "        r[i] = 1 /(1 + math.exp(params[i]))\n",
    "    return r\n",
    " \n",
    "def sigmodFormatrix2(Xb,thetas):\n",
    "    params = - Xb.dot(thetas)\n",
    "    r = np.zeros(params.shape[0])#返回一个np数组\n",
    "    for i in range(len(r)):\n",
    "        r[i] = 1 /(1 + math.exp(params[i]))\n",
    "        if r[i] >=0.5:\n",
    "            r[i] = 1\n",
    "        else:\n",
    "            r[i] = 0\n",
    "    return r\n",
    "def sigmod(Xi,thetas):\n",
    "    params = - np.sum(Xi * thetas)\n",
    "    r = 1 /(1 + math.exp(params))\n",
    "    return r\n",
    " \n",
    "class LinearLogsiticRegression(object):\n",
    "    thetas = None\n",
    "    m = 0\n",
    "    #训练\n",
    "    def fit(self,X,y,alpha = 0.01,accuracy = 0.00001):\n",
    "        #插入第一列为1，构成xb矩阵\n",
    "        self.thetas = np.full(X.shape[1]+1,0.5)\n",
    "        self.m = X.shape[0]\n",
    "        a = np.full((self.m,1),1)\n",
    "        Xb = np.column_stack((a,X))\n",
    "        dimension  = X.shape[1]+1\n",
    "        #梯度下降迭代\n",
    "        count = 1\n",
    "        while True:\n",
    "            oldJ = self.costFunc(Xb, y)\n",
    "            #注意预测函数中使用的参数是未更新的\n",
    "            c = sigmodFormatrix(Xb, self.thetas)-y\n",
    "            for j in range(dimension):\n",
    "                self.thetas[j] = self.thetas[j] -alpha * np.sum(c * Xb[:,j])\n",
    "            newJ = self.costFunc(Xb, y)\n",
    "            if newJ == oldJ or math.fabs(newJ - oldJ) < accuracy:\n",
    "                print(\"代价函数迭代到最小值，退出！\")\n",
    "                print(\"收敛到:\",newJ)\n",
    "                break\n",
    "            print(\"迭代第\",count,\"次!\")\n",
    "            print(\"代价函数上一次的差:\",(newJ - oldJ))\n",
    "            count += 1\n",
    " \n",
    "    #预测\n",
    "    def costFunc(self,Xb,y):\n",
    "        sum = 0.0\n",
    "        for i in range(self.m):\n",
    "            yPre = sigmod(Xb[i,], self.thetas)\n",
    "            #print(\"yPre:\",yPre)\n",
    "            if yPre ==1 or yPre == 0:\n",
    "                return infinity\n",
    "            sum += y[i]*math.log(yPre)+(1 - y[i])*math.log(1-yPre)\n",
    "        return -1/self.m * sum\n",
    "    def predict(self,X):\n",
    "        a = np.full((len(X),1),1)\n",
    "        Xb = np.column_stack((a,X))\n",
    "        return sigmodFormatrix2(Xb, self.thetas)\n",
    "    def score(self,X_test,y_test):\n",
    "        y_predict = myLogstic.predict(X_test)\n",
    "        re = (y_test==y_predict)\n",
    "        re1 = Counter(re)\n",
    "        a = re1[True] / (re1[True]+re1[False])\n",
    "        return a\n",
    "#if __name__==\"main\":\n",
    "# load data\n",
    "digits = load_digits()\n",
    "\n",
    "# plot the digits\n",
    "fig = plt.figure(figsize=(6, 6))  # figure size in inches\n",
    "fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)\n",
    "\n",
    "# plot the digits: each image is 8x8 pixels\n",
    "for i in range(64):\n",
    "    ax = fig.add_subplot(8, 8, i + 1, xticks=[], yticks=[])\n",
    "    ax.imshow(digits.images[i], cmap=plt.cm.binary)\n",
    "    \n",
    "    # label the image with the target value\n",
    "    ax.text(0, 7, str(digits.target[i]))\n",
    "df = pd.DataFrame(digits.data, columns=digits.feature_names)\n",
    "df['label'] = digits.target\n",
    "   \n",
    "data = np.array(df.iloc[:,:])\n",
    "\n",
    "\n",
    "X= data[:, 0:64]\n",
    "y = data[:, -1]\n",
    "X = X[y!=2]\n",
    "y=y[y!=2]\n",
    "X_train,X_test, y_train, y_test = train_test_split(X,y)\n",
    "myLogstic = LinearLogsiticRegression()    \n",
    "myLogstic.fit(X_train, y_train)\n",
    "y_predict = myLogstic.predict(X_test)\n",
    "print(\"参数:\",myLogstic.thetas)\n",
    "logr = LogisticRegression()\n",
    "logr.fit(X_train,y_train) \n",
    "print(\"测试数据准确度:\",logr.score(X_test,y_test)) \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "12905b56",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
